from PyQt4.QtCore import QDir
from PyQt4.QtCore import QVariant
from PyQt4.QtCore import Qt
from PyQt4.QtCore import SIGNAL
from PyQt4.QtGui import QAbstractItemView
from PyQt4.QtGui import QAction
from PyQt4.QtGui import QColumnView
from PyQt4.QtGui import QCursor
from PyQt4.QtGui import QDirModel
from PyQt4.QtGui import QHBoxLayout
from PyQt4.QtGui import QHeaderView
from PyQt4.QtGui import QItemSelectionModel
from PyQt4.QtGui import QListView
from PyQt4.QtGui import QMenu
from PyQt4.QtGui import QMessageBox
from PyQt4.QtGui import QStackedLayout
from PyQt4.QtGui import QTableView
from PyQt4.QtGui import QWidget
from PyQt4.QtGui import qApp
import os
import shutil


'''
Files represents view and model of file system
'''


class FilesRoom(QWidget):
    def __init__(self, phonik, root, view):

        #parent constructor
        QStackedLayout.__init__(self)

        self.phonik = phonik
        self.mediaManager = phonik.mediaManager
        self.root = root
        self.current = root

        self.filesModel = FilesModel(self);
        self.filesModel.setNameFilters(['..', '[^\.]*'])
        
        self.hlayout = QHBoxLayout(self)
        self.hlayout.setMargin(0)

        #gui
        if view == "icons":
            self.setIconsView()
        elif view == "table":
            self.setTableView()
        elif view == "columns":
            self.setColumnsView()

        
    def setRoot(self, root):
        self.filesView.setRootIndex(self.filesModel.index(root))
        self.current = self.filesModel.filePath(self.filesModel.index(root))


    def setColumnsView(self):
        self.filesModel.setFilter(QDir.AllEntries | QDir.NoDotAndDotDot)

        if hasattr(self, "filesView"):
            self.filesView.setHidden(True)

        if not hasattr(self, "columnsView"):
            self.columnsView = FilesColumnsView(self, self.filesModel)
            self.columnsView.setDragEnabled(True)
            self.hlayout.addWidget(self.columnsView)
        else:
            self.columnsView.setHidden(False)
        self.filesView = self.columnsView
        

        self.phonik.actionShowIcons.setChecked(False)
        self.phonik.actionShowTable.setChecked(False)
        self.phonik.actionShowColumns.setChecked(True)
        
        self.setRoot(self.root)


    def setIconsView(self):
        self.filesModel.setFilter(QDir.AllEntries)

        if hasattr(self, "filesView"):
            self.filesView.setHidden(True)

        if not hasattr(self, "iconsView"):
            self.iconsView = FilesIconsView(self, self.filesModel)
            self.iconsView.setDragEnabled(True)
            self.hlayout.addWidget(self.iconsView)
        else:
            self.iconsView.setHidden(False)
        self.filesView = self.iconsView

        self.phonik.actionShowIcons.setChecked(True)
        self.phonik.actionShowTable.setChecked(False)
        self.phonik.actionShowColumns.setChecked(False)

        self.setRoot(self.current)


    def setTableView(self):

        self.filesModel.setFilter(QDir.AllEntries)

        if hasattr(self, "filesView"):
            self.filesView.setHidden(True)

        if not hasattr(self, "tableView"):
            self.tableView = FilesTableView(self, self.filesModel)
            self.tableView.sortByColumn(0, Qt.AscendingOrder)
            self.tableView.setDragEnabled(True)
            self.hlayout.addWidget(self.tableView)
        else:
            self.tableView.setHidden(False)
        self.filesView = self.tableView

        self.phonik.actionShowIcons.setChecked(False)
        self.phonik.actionShowTable.setChecked(True)
        self.phonik.actionShowColumns.setChecked(False)

        self.setRoot(self.current)


    def showContextMenu(self, pos):
        
        actionList = [QAction(self.tr('Play recursively'), self), QAction(self.tr('Add to playlist'), self), QAction(self.tr('Delete'), self)]
        result = QMenu().exec_(actionList, QCursor.pos())
        
        if result and self.filesView.indexAt(pos).isValid:
                
            if result.text() == self.tr('Play recursively'):
                for fileIndex in self.filesView.selectedIndexes():
                    path = str(self.filesModel.filePath(fileIndex).toUtf8())
                    self.phonik.play(path, True)

            elif result.text() == self.tr('Add to playlist'):
                for fileIndex in self.filesView.selectedIndexes():
                    path = str(self.filesModel.filePath(fileIndex).toUtf8())
                    self.phonik.play(path, True, True)

            elif result.text() == self.tr('Delete'):
                res = QMessageBox.question(self, self.tr("Delete selected"), self.tr("Do you want to delete selected?"), QMessageBox.Yes, QMessageBox.No)
                if res == QMessageBox.Yes:
                    for fileIndex in self.filesView.selectedIndexes():
                        path = str(self.filesModel.filePath(fileIndex).toUtf8())
                        if os.path.isdir(path):
                            shutil.rmtree(path)
                        else:
                            os.remove(path)
                        self.filesModel.refresh()

        

class FilesColumnsView(QColumnView):
    def __init__(self, filesRoom, model):
        self.filesRoom = filesRoom

        #parent constructor
        QColumnView.__init__(self)
        self.setModel(model)

        self.setContextMenuPolicy(Qt.CustomContextMenu)
        self.connect(self, SIGNAL('customContextMenuRequested(const QPoint &)'), self.filesRoom.showContextMenu)
        self.connect(self, SIGNAL("doubleClicked(const QModelIndex &)"), self.doubleClicked)

            
    def doubleClicked(self, index):
        if qApp.keyboardModifiers () != Qt.ControlModifier and qApp.keyboardModifiers () != Qt.ShiftModifier:
            self.filesRoom.mediaManager.clearQueue()
            self.filesRoom.phonik.play(str(self.model().filePath(index).toUtf8()))



class FilesIconsView(QListView):
    def __init__(self, filesRoom, model):
        self.filesRoom = filesRoom

        #parent constructor
        QListView.__init__(self)
        self.setModel(model)

        self.setViewMode(QListView.IconMode)
        self.setSpacing(15)
        self.setWordWrap(True)
        self.setContextMenuPolicy(Qt.CustomContextMenu)
        self.setResizeMode(QListView.Adjust)
        self.setSelectionMode(QAbstractItemView.ExtendedSelection)
        self.setSelectionRectVisible(True)

        self.connect(self, SIGNAL('customContextMenuRequested(const QPoint &)'), self.filesRoom.showContextMenu)
        self.connect(self, SIGNAL("clicked(const QModelIndex &)"), self.clicked)
    
    def clicked(self, index):
        if qApp.keyboardModifiers () != Qt.ControlModifier:
            if self.model().isDir(index):
                self.filesRoom.setRoot(self.model().filePath(index))
            else:
                self.filesRoom.phonik.playUrls([str(self.model().filePath(index).toUtf8())])
        else:
            self.selectionModel().select(index, QItemSelectionModel.SelectCurrent)

    

class FilesTableView(QTableView):
    def __init__(self, filesRoom, model):
        self.filesRoom = filesRoom

        #parent constructor
        QListView.__init__(self)
        self.setModel(model)

        self.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.setShowGrid(False)
        self.setContextMenuPolicy(Qt.CustomContextMenu)
        self.horizontalHeader().setContextMenuPolicy(Qt.CustomContextMenu)
        self.horizontalHeader().setResizeMode(0, QHeaderView.Stretch)
        self.verticalHeader().setHidden(True)
        self.setSortingEnabled(True)

        self.connect(self, SIGNAL('customContextMenuRequested(const QPoint &)'), self.filesRoom.showContextMenu)
        self.connect(self, SIGNAL("clicked(const QModelIndex &)"), self.clicked)
        self.connect(self.horizontalHeader(), SIGNAL('customContextMenuRequested(const QPoint &)'), self.showHeaderContextMenu)

    def clicked(self, index):
        if qApp.keyboardModifiers () != Qt.ControlModifier:
            if self.model().isDir(index):
                self.filesRoom.setRoot(self.model().filePath(index))
            else:
                self.filesRoom.phonik.playUrls([str(self.model().filePath(index).toUtf8())])
        else:
            self.selectionModel().select(index, QItemSelectionModel.SelectCurrent)

    def showHeaderContextMenu(self):
        menu = QMenu()

        for i in range(0, self.model().columnCount()):
            action = menu.addAction(self.model().headerData(i, Qt.Horizontal).toString())
            action.setProperty('column', QVariant(i))
            action.setCheckable(True)
            if not self.isColumnHidden(i):
                action.setChecked(True)

        self.connect(menu, SIGNAL('triggered (QAction *)'), self.runHeaderContextMenu)
        menu.exec_(QCursor.pos())
        
    def runHeaderContextMenu(self, action):
        column = int(action.property('column').toString())
        self.setColumnHidden(column, not self.isColumnHidden(column))



class FilesModel(QDirModel):
    def __init__(self, parent=None):
        #parent constructor
        QDirModel.__init__(self, parent)

